#include "jcff_stc_int.h"

static void cirq_int0Enable(CIRQn_TypeDef CIRQn, IRQ_PriorityTypeDef IRQ_Priority);
static void cirq_int1Enable(CIRQn_TypeDef CIRQn, IRQ_PriorityTypeDef IRQ_Priority);
static void cirq_int234Enable(CIRQn_TypeDef CIRQn, IRQ_PriorityTypeDef IRQ_Priority);
static void cirq_t0t1Enable(CIRQn_TypeDef CIRQn, IRQ_PriorityTypeDef IRQ_Priority);
static void cirq_t2t3t4Enable(CIRQn_TypeDef CIRQn, IRQ_PriorityTypeDef IRQ_Priority);
static void cirq_uart1Enable(CIRQn_TypeDef CIRQn, IRQ_PriorityTypeDef IRQ_Priority);
static void cirq_uart234Enable(CIRQn_TypeDef CIRQn, IRQ_PriorityTypeDef IRQ_Priority);
static void cirq_adcEnable(CIRQn_TypeDef CIRQn, IRQ_PriorityTypeDef IRQ_Priority);
static void cirq_lvdEnable(CIRQn_TypeDef CIRQn, IRQ_PriorityTypeDef IRQ_Priority);
static void cirq_spiEnable(CIRQn_TypeDef CIRQn, IRQ_PriorityTypeDef IRQ_Priority);
/**
  * @brief  Enables a device common interrupt in the NVIC interrupt controller.
  * @note   
  * @param  CIRQn External interrupt number.
  * @retval None
  */
void INT_EnableCIRQ(CIRQn_TypeDef CIRQn, IRQ_PriorityTypeDef IRQ_Priority)
{
    switch (CIRQn)
    {
        case CIRQ_EINT0_BOTH_EDGE: 
        case CIRQ_EINT0_FALL_EDGE:
            cirq_int0Enable(CIRQn, IRQ_Priority);
            break;
        case CIRQ_EINT1_BOTH_EDGE:
        case CIRQ_EINT1_FALL_EDGE:
            cirq_int1Enable(CIRQn, IRQ_Priority);
            break;
        case CIRQ_EINT2_FALL_EDGE:
        case CIRQ_EINT3_FALL_EDGE:
        case CIRQ_EINT4_FALL_EDGE:
            cirq_int234Enable(CIRQn, IRQ_Priority);
            break;
        case CIRQ_T0:
        case CIRQ_T1:
            cirq_t0t1Enable(CIRQn, IRQ_Priority);
            break;
        case CIRQ_T2:
        case CIRQ_T3:
        case CIRQ_T4:
            cirq_t2t3t4Enable(CIRQn, IRQ_Priority);
            break;
        case CIRQ_UART1:
            cirq_uart1Enable(CIRQn, IRQ_Priority);
            break;
        case CIRQ_UART2:
        case CIRQ_UART3:
        case CIRQ_UART4:
            cirq_uart234Enable(CIRQn, IRQ_Priority);
            break;
        case CIRQ_ADC:
            cirq_adcEnable(CIRQn, IRQ_Priority);
            break;
        case CIRQ_LVD:
            cirq_lvdEnable(CIRQn, IRQ_Priority);
            break;
        case CIRQ_SPI:
            cirq_spiEnable(CIRQn, IRQ_Priority);
            break;
        default:
            break;
    }
}

/**
  * @brief  Enable the interrupt INT0 chanel.
  * @note   
  * @param  CIRQn External interrupt number.
  *         IRQ_Priority External interrupt priority
  * @retval None
  */
static void cirq_int0Enable(CIRQn_TypeDef CIRQn, IRQ_PriorityTypeDef IRQ_Priority)
{
    if(CIRQn == CIRQ_EINT0_BOTH_EDGE)
    {
        IT0 = 0;        //Enable both raise and falling edge interrupt of INT0
        EX0 = 1;        //Enable INT0 

    }
    else if(CIRQn == CIRQ_EINT0_FALL_EDGE)
    {
        IT0 = 1;        //Enable falling edge interrupt of INT0
        EX0 = 1;        //Enable INT0 
    }
    IP = (IP & 0xfe) | (IRQ_Priority & 0x01);
    IPH = (IPH & 0xfe) | ((IRQ_Priority & 0x02) >> 1); 
}

/**
  * @brief  Enable the interrupt INT1 chanel.
  * @note   
  * @param  CIRQn External interrupt number.
  *         IRQ_Priority External interrupt priority
  * @retval None
  */
static void cirq_int1Enable(CIRQn_TypeDef CIRQn, IRQ_PriorityTypeDef IRQ_Priority)
{
    if(CIRQn == CIRQ_EINT0_BOTH_EDGE)
    {
        IT1 = 0;        //Enable both raise and falling edge interrupt of INT0
        EX1 = 1;        //Enable INT0 

    }
    else if(CIRQn == CIRQ_EINT0_FALL_EDGE)
    {
        IT1 = 1;        //Enable falling edge interrupt of INT0
        EX1 = 1;        //Enable INT0 
    }
    IP = (IP & 0xfb) | ((IRQ_Priority & 0x01) << 2);
    IPH = (IPH & 0xfb) | ((IRQ_Priority & 0x02) << 1); 
}

/**
  * @brief  Enable the interrupt INT234 chanel.
  * @note   
  * @param  CIRQn External interrupt number.
  *         IRQ_Priority External interrupt priority
  * @retval None
  */
static void cirq_int234Enable(CIRQn_TypeDef CIRQn, IRQ_PriorityTypeDef IRQ_Priority)
{
    INTCLKO = INTCLKO & (~(0x01 << CIRQn)) | (0x01 << CIRQn);
    if(CIRQn == CIRQ_EINT4_FALL_EDGE)
    {
        IP2 = (IP2 & 0xf7) | ((IRQ_Priority & 0x01) << 4);
        IP2H = (IP2H & 0xf7) | ((IRQ_Priority & 0x02) << 3); 
    }
}

/**
  * @brief  Enable the interrupt timer 0 and timer 1 interrupt.
  * @note   
  * @param  CIRQn External interrupt number.
  *         IRQ_Priority External interrupt priority
  * @retval None
  */
static void cirq_t0t1Enable(CIRQn_TypeDef CIRQn, IRQ_PriorityTypeDef IRQ_Priority)
{
    if(CIRQn == CIRQ_T0)
    {
        ET0 = 1;
        IP = (IP & 0xfd) | ((IRQ_Priority & 0x01) << 1);
        IPH = (IPH & 0xfd) | (IRQ_Priority & 0x02);         
    }
    else if(CIRQn == CIRQ_T1)
    {
        ET1 = 1;
        IP = (IP & 0xf7) | ((IRQ_Priority & 0x01) << 3);
        IPH = (IPH & 0xf7) | ((IRQ_Priority & 0x02) << 2);    
    }
}

/**
  * @brief  Enable the interrupt timer 2, timer 3 and timer 4 interrupt.
  * @note   
  * @param  CIRQn External interrupt number.
  *         IRQ_Priority External interrupt priority
  * @retval None
  */
static void cirq_t2t3t4Enable(CIRQn_TypeDef CIRQn, IRQ_PriorityTypeDef IRQ_Priority)
{
    if(CIRQn == CIRQ_T2)
    {
        IE2 = (IE2 & (~TIM2_ENABLE_BIT)) | TIM2_ENABLE_BIT;
    }
    else if(CIRQn == CIRQ_T3)
    {
        IE2 = (IE2 & (~TIM3_ENABLE_BIT)) | TIM3_ENABLE_BIT;   
    }
    else if(CIRQn == CIRQ_T4)
    {
        IE2 = (IE2 & (~TIM4_ENABLE_BIT)) | TIM4_ENABLE_BIT;
    }
}

/**
  * @brief  Enable the interrupt UART1 interrupt.
  * @note   
  * @param  CIRQn External interrupt number.
  *         IRQ_Priority External interrupt priority
  * @retval None
  */
static void cirq_uart1Enable(CIRQn_TypeDef CIRQn, IRQ_PriorityTypeDef IRQ_Priority)
{
    if(CIRQn == CIRQ_UART1)
    {
        ES = 1;
        IP = (IP & 0xef) | ((IRQ_Priority & 0x01) << 4);
        IPH = (IPH & 0xef) | ((IRQ_Priority & 0x02) << 3);
    }
}

/**
  * @brief  Enable the interrupt UART2 ~ 4 interrupt.
  * @note   
  * @param  CIRQn External interrupt number.
  *         IRQ_Priority External interrupt priority
  * @retval None
  */
static void cirq_uart234Enable(CIRQn_TypeDef CIRQn, IRQ_PriorityTypeDef IRQ_Priority)
{
    ES = 1;
    if(CIRQn == CIRQ_UART2)
    {
        IE2 |= UART2_ENABLE_BIT;
        IP2 = (IP2 & 0xfe) | (IRQ_Priority & 0x01);
        IP2H = (IP2H & 0xfe) | ((IRQ_Priority & 0x02) >> 1);
    }
    else if(CIRQn == CIRQ_UART3)
    {
        IE2 |= UART3_ENABLE_BIT;
    }
    else if(CIRQn == CIRQ_UART4)
    {
        IE2 |= UART4_ENABLE_BIT;
    }
}

/**
  * @brief  Enable the ADC interrupt.
  * @note   
  * @param  CIRQn External interrupt number.
  *         IRQ_Priority External interrupt priority
  * @retval None
  */
static void cirq_adcEnable(CIRQn_TypeDef CIRQn, IRQ_PriorityTypeDef IRQ_Priority)
{
    EADC = 1;
    IP2 = (IP2 & 0xdf) | ((IRQ_Priority & 0x01) << 5);
    IP2H = (IP2H & 0xdf) | ((IRQ_Priority & 0x02) << 4);    
}

/**
  * @brief  Enable the LVD interrupt.
  * @note   
  * @param  CIRQn External interrupt number.
  *         IRQ_Priority External interrupt priority
  * @retval None
  */
static void cirq_lvdEnable(CIRQn_TypeDef CIRQn, IRQ_PriorityTypeDef IRQ_Priority)
{
    ELVD = 1;
    IP = (IP & 0xbf) | ((IRQ_Priority & 0x01) << 6);
    IPH = (IPH & 0xbf) | ((IRQ_Priority & 0x02) << 5);    
}

/**
  * @brief  Enable the LVD interrupt.
  * @note   
  * @param  CIRQn External interrupt number.
  *         IRQ_Priority External interrupt priority
  * @retval None
  */
static void cirq_spiEnable(CIRQn_TypeDef CIRQn, IRQ_PriorityTypeDef IRQ_Priority)
{
    IE2 |= SPI_ENABLE_BIT;
    IP2 = (IP2 & 0xfd) | ((IRQ_Priority & 0x01) << 1);
    IP2H = (IP2H & 0xfd) | ((IRQ_Priority & 0x02));        
}

